<template>
  <div class="box" ref="box">
    <div v-if="isBtn">
      <el-button type="primary" icon="search" :disabled="disabledSearch" @click="onclick">{{ btnShowText }}</el-button>
    </div>
    <el-form-item v-else :error="errMs" :style="style" style="margin: 0">
      <el-input ref="input"
                v-model="input"
                clearable
                :size="size"
                :title="input"
                :style="style"
                :placeholder="placeholder"
                :disabled="disabled"
                :debounce="1000"
                :fetch-suggestions="querySearchAsync"
                :trigger-on-focus="false"
                :readonly="readonly"
                @blur.stop.native="onblur"
                @select="handleSelect"
                @clear="onTableRowClick({});errMs = '';">
        <!--
        <template #prefix>
          <div style="cursor: pointer" @click="isMultiple = !isMultiple">{{ isMultiple ? '多选' : '单选' }}</div>
        </template>
        -->
        <template #append>
          <el-button :disabled="disabledSearch" @click="onclick" icon="Search"/>
        </template>
        <template #default="{ item }">
          <div @mouseenter="onmouseenter" @mouseleave="onmouseleave">
            <slot name="selectItem" :item="item"></slot>
          </div>
        </template>
      </el-input>
    </el-form-item>
  </div>
  <div class="my-dialog">
    <el-dialog draggable
               v-model="open"
               :title="title"
               :before-close="handleClose"
               width="70%"
               destroy-on-close
               append-to-body>
      <div>
        <el-row>
          <el-col :span="24">
            <el-form ref="filterFrom" :model="listQuery" size="small" :inline="true" class="demo-form-inline">
              <slot name="queryFrom" :listQuery="listQuery" :handleFilter="handleFilter"></slot>
              <el-form-item>
                <el-button v-waves type="success" icon="Search" @click="handleFilter">
                  查询
                </el-button>
                <el-button v-waves icon="Refresh" @click="handleResetQuery">
                  重置
                </el-button>
              </el-form-item>
            </el-form>
          </el-col>
        </el-row>
        <el-row>
          <el-divider class="el-divider--horizontal-margin"/>
          <el-col :span="24">
            <MultiplePageSelectionTable v-if="isMultiple" :isExist="isExist" ref="mpTable"
                                        :max-height="maxHeight" :keyName="keyName" :keyShow="keyShow"
                                        @onchange="handleSelectionChange">
              <template #tableColumn>
                <slot name="queryTable"></slot>
              </template>
            </MultiplePageSelectionTable>
            <el-table v-else :row-key="rowKey" :row-class-name="rowClassName"
                      ref="tab"
                      :data="tableDialogData"
                      v-loading="loading"
                      @row-click="(row,column,event) => onTableRowClick(row,column,event)">
              <slot name="queryTable"></slot>
            </el-table>
            <pagination v-model:total="total" v-model:page="listQuery.pageNum" v-model:limit="listQuery.pageSize" @pagination="getList"/>
            <!--
            <el-table :row-key="rowKey" :row-class-name="rowClassName"
                      ref="tab"
                      :data="tableDialogData"
                      v-loading="loading"
                      @row-click="(row,column,event) => onTableRowClick(row,column,event)">
              <slot name="queryTable"></slot>
            </el-table>
            <pagination v-model:total="total" v-model:page="listQuery.pageNum" v-model:limit="listQuery.pageSize" @pagination="getList"/>
            -->
          </el-col>
        </el-row>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary" icon="Check" @click="handleOk">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import {doGet} from '@/config/http'
import InputTag from "@/components/InputTag/index.vue";
import {svc, isNullOrUndefinedOrEmpty} from "@/config/common";
import MultiplePageSelectionTable from "@/components/MultiplePageSelectionTable/index.vue";

export default {
  name: "index",
  components: {MultiplePageSelectionTable, InputTag},
  emits: ['update:modelValue', 'onchange', 'changeErrMs', 'callback'],
  props: {
    rowKey: {
      type: String,
      default: 'id'
    },
    rowClassName: {
      type: Function,
      default: function () {
        return ''
      }
    },
    placeholder: {
      type: String,
      default: ''
    },
    modelValue: String,
    keyName: {
      type: String,
      required: true,
    },
    keyShow: {
      type: String,
      required: true,
    },
    isNotShow: {
      type: Boolean,
      default: false
    },
    size: {
      default: 'default'
    },
    svc: {
      type: String,
      default: svc
    },
    urlPage: {type: String, required: true},
    urlIds: {type: String, required: true},
    style: {
      default: ''
    },
    title: {
      type: String
    },
    isDataList: {
      type: Boolean,
      default: false
    },
    params: {
      type: Object,
      default() {
        return {}
      }
    },
    disabled: {
      type: Boolean,
      default: false
    },
    searchEnabled: {
      type: Boolean,
      default: false
    },
    readonly: {
      type: Boolean,
      default: false
    },
    //是否添加重新渲染描述
    isAddDes: {
      type: Boolean,
      default: false
    },
    //列表清空，输入错误值清空
    clearValue: {
      type: Boolean,
      default: false
    },
    isMultiple: {
      type: Boolean,
      default: false
    },
    maxHeight: {
      type: String,
      default: '600'
    },
    isExist: {
      type: Function,
      default: (row, item, rowKey = 'id') => {
        return row[rowKey] === item[rowKey]
      }
    },
    isBtn: {
      type: Boolean,
      default: false
    },
    btnShowText: {
      type: String,
      default: '选择'
    }
  },
  data() {
    return {
      row: null,
      input: '',
      open: false,
      loading: false,
      listQuery: {
        pageNum: 1,
        pageSize: 10,
      },
      changeData: {
        pageNum: 1,
        pageSize: 10,
      },
      tableDialogData: [],
      total: 0,
      tStop: null,
      list: null,
      errMs: '',
      isNotEnter: true,
      isNotInit: false,
      isSearchAsync: false,
      activeName: 'query',
      selectionList: []
    }
  },
  computed: {
    disabledSearch() {
      const {searchEnabled, disabled} = this
      if (searchEnabled) {
        return false
      }
      return disabled
    }
  },
  watch: {
    params: {
      immediate: true,
      deep: true,
      handler(val) {
        Object.assign(this.listQuery, val)
      }
    },
    modelValue: {
      handler: function (val, old) {
        console.debug('val--------------', val)
        console.debug('this.keyShow', this.keyShow)
        if (!isNullOrUndefinedOrEmpty(val) && !isNullOrUndefinedOrEmpty(this.urlIds)) {
          doGet(svc, this.urlIds, {ids: val}, false).then(res => {
            this.input = res?.map(m => m[this.keyShow]).join(',')
          })
        }
        if (!this.open && val !== old) {
          this.init()
        }
      },
      immediate: true
    },
    clearValue: {
      handler(val) {
        if (val) {
          this.input = ''
        }
      },
      immediate: true
    }
  },
  created() {
    this.init()
  },
  methods: {
    init() {
      this.input = this.modelValue
      console.debug('this.input+++++', this.input)
      this.row = null
      if (this.isNotInit) {
        return false
      }
      if (this.params) {
        Object.assign(this.listQuery, this.params)
      }
    },
    handleClose() {
      this.open = false
    },
    onclick() {
      this.listQuery = {
        ...this.params,
        pageNum: 1,
        pageSize: 10,
      }
      this.open = true

      this.getList()
    },
    handleSelect(row) {
      this.$refs.input.blur()
      this.row = row
      this.onTableRowClick(this.row)
      this.isSearchAsync = false
    },
    onTableRowClick(row, column, event, isAuto) {
      if (row.disabled) {
        return false
      }
      this.row = row
      if (this.isNotShow) {
        this.input = ''
      } else {
        this.input = this.row && (this.keyShow && this.row[this.keyShow]) || this.row[this.keyName] || ''
        if (!this.input) {
          this.$nextTick(() => {
            setTimeout(() => {
              this.$refs.input.blur()
            })
          })
        }
      }
      this.isNotInit = true
      this.$emit('update:modelValue', row[this.keyName])
      this.$emit('onchange', row, isAuto)
      setTimeout(() => {
        this.isNotInit = false
      })
      this.errMs = ''
      this.$emit('changeErrMs', this.errMs, this.input)
      setTimeout(() => {
        this.open = false
      })
    },
    handleSelectionChange(data) {
      this.selectionList = data
    },
    handleOk() {
      if (this.isMultiple) {
        this.input = this.selectionList.map(item => {
          return item[this.rowKey]
        }).join(',')
        this.$emit('update:modelValue', this.input)
        this.$emit('onchange', this.selectionList)
      }
      this.open = false
    },
    handleFilter() {
      this.listQuery.pageNum = 1
      this.getList()
      if (this.isMultiple) {
        this.$refs.mpTable?.initSelect()
      }
    },
    handleResetQuery() {
      this.$refs.filterFrom.resetFields()
    },
    getList() {
      //自定义方法嵌套组件冒泡，没啥好的解决办法，同时解决多组件同时请求
      this.tStop = setTimeout(() => {
        if (this.tStop) {
          clearTimeout(this.tStop)
        }
        this.loading = true
        doGet(svc, this.urlPage, this.listQuery, false).then(res => {
          if (res && res?.records && res.records?.length > 0 || (this.isDataList && res?.length > 0)) {
            if (this.isDataList) {
              this.tableDialogData = res
              this.total = 0
            } else {
              this.tableDialogData = res?.records
              this.total = parseInt(res['total']) || 0
            }
            if (this.isAddDes) {
              this.$emit('callback', this.tableDialogData)
            }
          } else {
            this.tableDialogData = []
            this.total = 0
          }
          if (this.isMultiple) {
            this.$refs.mpTable?.setList(this.tableDialogData)
          }
          this.loading = false
        })
      })
    },
    querySearchAsync(queryString, cb) {
      // this.isSearchAsync = true
      let list = []
      if (this.isNotEnter && queryString.length > 0) {
        this.errMs = ''
        let params = {
          ...this.params,
          pageNum: 1,
          pageSize: 100
        }
        params[this.keyName] = queryString
        doGet(svc, this.urlPage, params, false).then(res => {
          if (res && res?.records && res.records.length > 0 || (this.isDataList && res?.length > 0)) {
            if (this.isDataList) {
              list = res
            } else {
              list = res?.records
              this.total = parseInt(res['total'])
            }
            if (this.isAddDes) {
              this.$emit('callback', list)
              setTimeout(() => {
                cb && cb(list)
              }, 500)
            } else {
              cb && cb(list)
            }
          } else {
            this.errMs = ' '
            cb && cb(list)
          }
          // this.isSearchAsync = false
        })
      } else {
        cb && cb(list)
        // this.isSearchAsync = false
      }
    },
    onblur() {
      this.isChange = false
      this.tOpenTable = setTimeout(() => {
        this.input = this.row && (this.keyShow && this.row[this.keyShow] || this.row[this.keyName]) || ''
      }, 300)
    },
    handleInputTag() {
      this.$emit('update:modelValue', this.input)
    },
    onmouseenter() {
      this.isSearchAsync = true
    },
    onmouseleave() {
      this.isSearchAsync = false
    }
  }
}
</script>

<style scoped lang="scss">
:deep() {
  .el-table__row.disabled {
    td {
      background-color: #f5f7fa;
    }
  }

  .el-table__row.disabled:hover {
    cursor: no-drop;
  }
}

.box {
  position: relative;
  width: 100%;
  display: contents;

  .my-table {
    position: absolute;
    z-index: 9999;
  }
}

.my-dialog {
  :deep(.pagination-container) {
    margin-top: 0;
  }

  :deep(.el-dialog__body) {
    padding-top: 0;
    padding-bottom: 10px;
  }
}
</style>
